package cn.com.xy.sms.sdk.service.expressinfoservice;

import java.util.Map;

import org.json.JSONArray;
import org.json.JSONObject;

import android.os.Process;
import cn.com.xy.sms.sdk.Iservice.XyCallBack;
import cn.com.xy.sms.sdk.constant.Constant;
import cn.com.xy.sms.sdk.log.LogManager;
import cn.com.xy.sms.sdk.net.NetUtil;
import cn.com.xy.sms.sdk.threadpool.SmartSmsThreadPoolManager;
import cn.com.xy.sms.sdk.util.CallBackState;
import cn.com.xy.sms.sdk.util.SdkCache;
import cn.com.xy.sms.sdk.util.StringUtils;
import cn.com.xy.sms.sdk.util.XyUtil;
import cn.com.xy.sms.util.ParseSmsMessage;
import cn.com.xy.sms.util.SdkCallBack;

public class ExpressInfoService {

    private static final String TAG = "ExpressInfoService";

    private static final long CYCLE_LONG = 60 * 1000;

    private static long LATEST_UPDATE_LONG = 0l;

    public static void getExpressInfoData(final String msgId, final String phoneNum, final String expressNum,
            final Map<String, String> extend, final SdkCallBack xyCallBack, boolean scrollFing) {

        try {
            if (StringUtils.isNull(msgId) || StringUtils.isNull(phoneNum) || StringUtils.isNull(expressNum)) {
                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_NODATA, " param error",
                        msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_EXPRESS_INFO_FLAG);
                return;
            }
            
            final String key = msgId + expressNum;

            final SdkCache sdkCache = SdkCache.createSdkCache(phoneNum);

            JSONObject res = sdkCache.effectiveExpressInfoData.get(key);
            if (res != null) {
                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_HASDATA, res, msgId,
                        ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_EXPRESS_INFO_FLAG);
                updateExpressInfo(msgId, expressNum, sdkCache, key, xyCallBack);
                return;
            }

            if (sdkCache.inQueueExpressInfoData.contains(key)) {
                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_NODATA,
                        " inQueueExpressInfoData", msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_EXPRESS_INFO_FLAG);
                return;
            }

            if (!scrollFing) {
                sdkCache.inQueueExpressInfoData.add(key);
                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_NEEDPARSE, " need parse",
                        msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_EXPRESS_INFO_FLAG);

                SmartSmsThreadPoolManager.getMsgUrlPool().execute(new Runnable() {

                    @Override
                    public void run() {
                        try {
                            SmartSmsThreadPoolManager.setThreadNameAndPriority(
                                    SmartSmsThreadPoolManager.TNAME_MSGURLPOOL, Process.THREAD_PRIORITY_BACKGROUND);
                            requestExpressInfo(msgId, expressNum, sdkCache, key, xyCallBack);
                        } catch (Throwable e) {
                        }
                    }
                });

            } else {
                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_SCOLLING, " is scrolling",
                        msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_EXPRESS_INFO_FLAG);
            }
        } catch (Throwable e) {
        }
    }

    public static synchronized void updateExpressInfo(final String msgId, final String expressNum, final SdkCache sdkCache,
            final String key, final SdkCallBack xyCallBack) {

        if (System.currentTimeMillis() < LATEST_UPDATE_LONG + CYCLE_LONG)
            return;

        executeRunnable(new Runnable() {
            @Override
            public void run() {
                try {
                    ExpressInfoNetBatch(msgId, expressNum, sdkCache, key, xyCallBack);
                } catch (Throwable e) {
                }

            }
        });

    }

    public static void ExpressInfoNetBatch(final String msgId, final String expressNum, final SdkCache sdkCache,
            final String key, final SdkCallBack xyCallBack) {
        if (StringUtils.isNull(expressNum))
            return;
        try {
            final String dataString = getExpressInfoReq(expressNum);

            if (!StringUtils.isNull(dataString)) {
                NetUtil.requestNewTokenIfNeed(null);
                XyCallBack callBack = new XyCallBack() {

                    @Override
                    public void execute(Object... obj) {

                        if (obj == null || obj.length < 1) {
                            return;
                        }
                        int requestCode = (Integer) obj[0];

                        if (requestCode == CallBackState.REQUEST_SUCCESS) {

                            String response = obj[1].toString();
                            if (!StringUtils.isNull(response)) {
                                try {
                                    JSONObject resultObj = new JSONObject(response);
                                    JSONArray dataArr = resultObj.optJSONArray("data");
                                    JSONObject result = null;
                                    if (dataArr != null) {
                                        result = dataArr.optJSONObject(0);
                                    }
                                    if (result != null && (result.has("status") || result.has("num"))) {
                                        String num = result.optString("num");
                                        if (result.has("status") || expressNum.equalsIgnoreCase(num)) {
                                            sdkCache.inQueueExpressInfoData.remove(key);
                                            sdkCache.effectiveExpressInfoData.put(key, result);
                                            XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_BACKTHREAD_HASDATA,
                                                    result, msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_EXPRESS_INFO_FLAG);
                                        }
                                    }
                                } catch (Throwable e) {
                                }
                            }
                        }else{
                            XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_BACKTHREAD_FAIL,
                                    " no data", msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_EXPRESS_INFO_FLAG);
                        }
                    }
                };

                NetUtil.executeServiceHttpRequest(NetUtil.URL_EXPRESS_INFO, dataString, null, callBack);
            }
        } catch (Throwable e) {
        } finally {
            synchronized (ExpressInfoService.class) {
                LATEST_UPDATE_LONG = System.currentTimeMillis();
            }
        }
    }

    private static void requestExpressInfo(final String msgId, final String expressNum, final SdkCache sdkCache,
            final String key, final SdkCallBack xyCallBack) {
        try {
            XyCallBack callBack = new XyCallBack() {
                @SuppressWarnings("unused")
                @Override
                public void execute(Object... obj) {

                    try {
                        if (obj != null && obj.length > 1) {

                            int requestCode = (Integer) obj[0];
                            if (requestCode != CallBackState.REQUEST_SUCCESS) {
                                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_BACKTHREAD_FAIL,
                                        " no data", msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_EXPRESS_INFO_FLAG);
                                return;
                            }

                            JSONObject resultObj = new JSONObject((String) obj[1]);
                            if (resultObj == null) {
                                return;
                            }
                            JSONArray dataArr = resultObj.optJSONArray("data");
                            if (dataArr != null && dataArr.length() > 0) {
                                JSONObject result = dataArr.optJSONObject(0);
                                if (result == null || result.length() == 0) {
                                    return;
                                }
                                sdkCache.inQueueExpressInfoData.remove(key);
                                sdkCache.effectiveExpressInfoData.put(key, result);
                                XyUtil.doXycallBackResult(xyCallBack, ParseSmsMessage.DUOQU_CALLBACK_BACKTHREAD_HASDATA,
                                        result, msgId, ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_EXPRESS_INFO_FLAG);
                            }
                        }
                    } catch (Throwable e) {
                    }
                }
            };

            JSONObject params = new JSONObject();
            JSONArray jsonArr = new JSONArray();
            jsonArr.put(expressNum);
            params.put("data", jsonArr);
            NetUtil.executeServiceHttpRequest(NetUtil.URL_EXPRESS_INFO, params.toString(), null, callBack);
        } catch (Throwable e) {
        } finally {
            synchronized (ExpressInfoService.class) {
                LATEST_UPDATE_LONG = System.currentTimeMillis();
            }
        }
    }

    public static void executeRunnable(Runnable runnable) {
        SmartSmsThreadPoolManager.netWebPool.execute(runnable);
    }

    public static String getExpressInfoReq(String expressNum) {
        try {

            JSONArray jsonArray = new JSONArray();
            jsonArray.put(expressNum);
            JSONObject json = new JSONObject();
            json.put("data", jsonArray);
            return json.toString();
        } catch (Exception e) {
            LogManager.e(Constant.TAG, "ServerUtil getExpressInfoReq(JSONArray phoneJsonArray): ", e);
        }
        return "";
    }

}
